package com.exam.api.modules.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.exam.api.common.dto.KeywordDTO;
import com.exam.api.modules.system.domain.TblDept;
import com.exam.api.modules.system.dto.DeptAddDTO;
import com.exam.api.modules.system.dto.DeptIdDTO;
import com.exam.api.modules.system.dto.DeptQueryDTO;
import com.exam.api.modules.system.dto.DeptUpdateDTO;
import com.exam.api.modules.system.mapper.TblDeptMapper;
import com.exam.api.modules.system.service.TblDeptService;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 部门逻辑接口类实现类
 *
 * @author bcheng
 */
@Service
public class TblDeptServiceImpl extends ServiceImpl<TblDeptMapper, TblDept> implements TblDeptService {


    @Override
    public List<Long> listParentChildDeptIds(Long parentId) {
        List<Tree<Long>> trees = treeDept(new KeywordDTO());
        return trees.stream().map(tree -> {
            Tree<Long> node = tree.getNode(parentId);
            if (node == null || !node.isEmpty()) {
                return null;
            }
            return TreeUtil.getParentsId(node, true);
        }).filter(Objects::nonNull).flatMap(List::stream).collect(Collectors.toList());
    }


    @Override
    public List<Tree<Long>> treeDept(KeywordDTO dto) {
        List<TblDept> list = lambdaQuery()
                .select(TblDept::getDeptId, TblDept::getParentDeptId, TblDept::getName, TblDept::getLevel)
                .like(StrUtil.isNotEmpty(dto.getKeyword()), TblDept::getName, dto.getKeyword())
                .orderByDesc(TblDept::getSort)
                .list();
        //配置
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey("deptId");
        config.setParentIdKey("parentDeptId");
        config.setWeightKey("sort");
        return TreeUtil.build(list, 0L, config, (node, tree) -> {
            tree.setId(node.getDeptId());
            tree.setParentId(node.getParentDeptId());
            tree.setWeight(node.getSort());
            tree.setName(node.getName());
            tree.putExtra("level", node.getLevel());
            tree.putExtra("createTime", node.getCreateTime());
        });
    }

    @Override
    public List<TblDept> listDept(DeptQueryDTO dto) {
        List<TblDept> list = lambdaQuery()
                .in(ObjUtil.isNotEmpty(dto.getDeptIds()), TblDept::getDeptId, dto.getDeptIds())
                .eq(ObjUtil.isNotEmpty(dto.getParentDeptId()), TblDept::getParentDeptId, dto.getParentDeptId())
                .like(StrUtil.isNotEmpty(dto.getKeyword()), TblDept::getName, dto.getKeyword())
                .orderByDesc(TblDept::getSort)
                .list();
        return list;
    }

    @Override
    public TblDept getDept(DeptIdDTO dto) {
        return getById(dto.getDeptId());
    }

    @Override
    public void addDept(DeptAddDTO dto) {
        TblDept dept = dto.converter();
        save(dept);
    }

    @Override
    public void updateDept(DeptUpdateDTO dto) {
        TblDept dept = dto.converter();
        updateById(dept);
    }

    @Override
    public void deleteDept(DeptIdDTO dto) {
        removeById(dto.getDeptId());
    }

    @Override
    public Map<Long, String> getNameMapByDeptIds(Collection<Long> deptIds) {
        if (CollUtil.isEmpty(deptIds)){
            return Collections.emptyMap();
        }
        List<TblDept> list = lambdaQuery()
                .select(TblDept::getDeptId, TblDept::getName)
                .in(TblDept::getDeptId, deptIds)
                .list();
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyMap();
        }
        return list.stream().collect(Collectors.toMap(TblDept::getDeptId, TblDept::getName));
    }
}
